跳至主要内容

課程:Redux 思維與 RTK 核心 第 1 堂:Redux 思維建立

04從傳統 Redux 到 RTK

如果在一場開發者聚會中提到「Redux」,你很可能會聽到兩種截然不同的反應。資深開發者可能會感嘆它嚴謹的架構與強大的除錯能力,而新手或是曾被「傳統寫法」折磨過的開發者,則可能會露出痛苦的面孔,抱怨那寫不完的樣板程式碼(Boilerplate)。

為什麼一個標榜著「可預測性」與「嚴謹性」的工具,會讓這麼多開發者感到畏懼?

在我們學過了 Action、Reducer 與 Store 的資料流運作後,你可能會覺得:「邏輯聽起來很清晰,但如果要為了改一個數字而寫這麼多程式碼,是不是有點太累了?」你的直覺是對的。這正是為什麼 Redux Toolkit (RTK) 會誕生,並且成為今天官方唯一推薦的寫法。

這一部分,我們將深入探討傳統 Redux 的痛點,並揭開 RTK 是如何優雅地解決這些問題,同時又不破壞我們引以為傲的三大原則。

傳統 Redux 的三大難題

在 RTK 出現之前,寫 Redux 就像是在進行一場充滿儀式感的修行。為了實現一個最簡單的「加一」功能,你需要經歷一段漫長的開發流程。

1. 永無止境的樣板程式碼 (Boilerplate)

在傳統寫法中,要定義一個狀態更新,通常需要完成以下三個步驟:

  1. 定義 Action Type 字串:為了避免打錯字,我們會先定義一個常數,例如 const INCREMENT = 'counter/increment';
  2. 撰寫 Action Creator 函式:我們需要一個函式來回傳 Action 物件,例如 const increment = () => ({ type: INCREMENT });
  3. 在 Reducer 中撰寫 Switch-case:我們要在一個巨大的 Reducer 函式中,根據不同的 action.type 來決定如何處理狀態。

這就是所謂的「樣板程式碼」。每增加一個小功能,你都要在多個檔案(或同檔案的多處)跳來跳去。這不僅增加了開發成本,更讓程式碼變得難以閱讀——邏輯被拆散在各地,你很難一眼看出「這個按鈕按下去,到底發生了什麼事」。

2. 手寫不可變更新 (Immutable Updates) 的痛苦

還記得 Redux 的第二大原則嗎?State 是唯讀的。我們不能直接修改 state,而必須回傳一個「全新的 state 物件」。

在傳統 Redux 中,我們重度依賴 JavaScript 的展開運算子 (...state)。如果你的狀態結構很簡單,那還好;但如果遇到巢狀物件(Nested Objects),程式碼就會變成一場災難:

// 傳統 Redux 的巢狀更新範例
case UPDATE_USER_CITY:
return {
...state,
user: {
...state.user,
address: {
...state.user.address,
city: action.payload
}
}
};

這種寫法極度容易出錯。只要漏掉一個 ...,你的部分狀態就會在這次更新中「神隱」。這種「手動維護不可變性」的過程,是許多 React 開發者對 Redux 望而卻步的主因。

3. 設定過程極其繁瑣

如果你想在傳統 Redux 專案中啟用 Redux DevTools 或處理非同步邏輯(如 redux-thunk),你必須在建立 Store 時進行繁雜的配置:

  • 手動調用 combineReducers
  • 手動串接 applyMiddleware
  • 手動檢查環境變數以決定是否開啟開發者工具。

對於想快速啟動專案的開發者來說,這些「基礎建設」的成本高得嚇人。


Redux Toolkit:現代開發的救星

Redux 官方意識到了這些痛點。他們並不想改變 Redux 的核心哲學,而是想改變開發者的「寫作體驗」。於是,Redux Toolkit (RTK) 應運而生。

RTK 並不是一個與 Redux 競爭的新框架,它是 Redux 的「標準封裝」。它就像是為你的手動排檔車換上了頂級的自排系統,核心引擎沒變,但開起來順暢多了。

核心 API 1:createSlice —— 讓 Action 與 Reducer 合而為一

這是 RTK 最具革命性的改進。createSlice 允許你將「初始狀態」、「Reducer 邏輯」與「Action」寫在同一個物件裡。

想像一下:以前你要分別定義 Action Type、Action Creator 和 Reducer,現在你只需要定義一個名稱叫做 counter 的 Slice,RTK 就會自動幫你生成對應的 Action Types(例如 counter/increment)和 Action Creators。

你不再需要手寫 switch-case,也不再需要擔心字串打錯的問題。所有的邏輯都被高度封裝在「切片 (Slice)」的概念中。

核心 API 2:內建 Immer —— 魔法般的「可變」語法

還記得剛才那個讓人頭痛的展開運算子嗎?在 RTK 的 createSlice 內部,它整合了一個強大的函式庫叫做 Immer

Immer 的運作機制非常巧妙:它會提供一個狀態的「草稿 (Draft)」。你可以在這個草稿上直接進行修改,就像你平時修改普通 JavaScript 物件一樣。

  • 預測:如果你寫下 state.user.value += 1,Redux 的狀態會被破壞嗎?
  • 揭曉:不會。因為 Immer 會在背後監控這些修改,並根據你的修改自動生成一個全新的、不可變的 State。

這意味著你可以寫出最直覺的程式碼,同時仍然嚴格遵守 Redux 的「不可變更新」原則。這不僅減少了代碼量,更徹底消滅了因為漏寫展開運算子而產生的 Bug。

核心 API 3:configureStore —— 聰明的預設設定

傳統的 createStore 就像是給你好幾個零件讓你組裝;而 configureStore 則像是提供了一個已經配備完善的豪華座駕。

當你使用 configureStore 時:

  • 它會自動幫你組合多個 Reducers。
  • 它預設就開啟了 Redux DevTools,你不需要寫任何額外的配置。
  • 它自動加入了 redux-thunk(用於非同步)以及開發環境下的「狀態修改偵測(Serializability check)」等 Middleware。

你只需要專注於定義你的業務邏輯,基礎建設的事情,交給 RTK 就好。


RTK 的本質:它仍然是 Redux

在學習 RTK 的過程中,新手最容易產生的誤解是:「我是在學一個叫 RTK 的新東西,而不是在學 Redux。」

請記住:RTK 就是 Redux。

它完全遵循我們在上一章節學到的 資料單向流動 (Unidirectional Data Flow)

  1. 你依然需要透過 Dispatch 發送一個 Action
  2. Reducer 依然是一個純函式(雖然有了 Immer 讓它看起來像在修改狀態,但本質上它仍然回傳新物件)。
  3. Store 依然是唯一的實體。

RTK 的出現並不是要推翻 Redux 的三大原則,相反地,它是為了更好地實踐這三大原則。透過自動化生成的 Action 與內建的不可變性處理,RTK 讓「做正確的事(遵守原則)」變得比「做錯誤的事(直接修改狀態)」更容易。

這就是所謂的 「有意見的 (Opinionated)」框架設計。它幫你選好了最佳實踐,讓你少走彎路。


為什麼這對你的鐵人賽文章至關重要?

當你在撰寫關於 Redux 的教學文章時,區分「傳統寫法」與「現代 RTK 寫法」是非常關鍵的。這不僅展現了你的知識深度,更能幫助讀者理解技術演進的脈絡。

如果你直接教 RTK 而不解釋它解決了什麼問題,讀者可能會覺得 createSlice 的語法很神奇,但不知道為什麼要這麼麻煩地定義 Slice。反之,如果你先點出傳統寫法的痛苦(樣板程式碼、展開運算子的風險),讀者在看到 RTK 的簡潔語法時,就會產生那種「Aha! Moment」——這就是他們會持續追蹤你文章的原因。

本課程的實作策略

在接下來的課程中,我們將全方位採用 RTK + TypeScript 的組合。

  • 我們會利用 createSlice 的型別推導能力,確保開發過程中的型別安全。
  • 我們會透過 configureStore 建立起一個結構清晰的 Store 專案架構。
  • 我們將不再手寫任何一個傳統的 Action Type 常數。

這套寫法不僅是官方推薦,更是目前業界在處理大型專案時的標準配置。


建立正確的技術心智模型

總結這堂課我們所建立的 Redux 世界觀:

  1. 為什麼需要狀態管理? 因為 Props Drilling 會讓開發變成地獄,而 Context API 在效能與除錯上有其侷限。
  2. Redux 的靈魂是什麼? 是「三大原則」。單一來源、狀態唯讀、純函式更新,這三者共同創造了「可預測性」。
  3. 資料怎麼動? 永遠是單向的。從 View 觸發 Action,交給 Reducer 運算,最後更新 Store 並回傳給 View。
  4. 為什麼要用 RTK? 因為傳統 Redux 寫起來太痛苦。RTK 透過 createSlice 和 Immer 等工具,讓我們能用最少的程式碼,寫出最符合原則的邏輯。

掌握了這些思維邏輯後,你已經跨過了 Redux 最難的一道關卡——「理解為什麼」。剩下的 API 用法與語法細節,都只是為了實踐這些想法的工具而已。

邁向實作的第一步

我們已經完成了完整的思維建模。現在,你的腦中已經有了一張清楚的地圖,知道我們從哪裡來(Props Drilling 的痛),也知道我們要往哪裡去(簡潔的 RTK 實作)。

下一堂課,我們將離開理論的舒適區,進入真正的程式碼世界。我們將從環境建置開始,手把手帶你使用 Vite 建立一個現代化的 React + TypeScript 專案,並安裝所有必要的 Redux 齒輪。準備好你的終端機,我們要開始動手建構你的第一個專業級狀態管理系統了。給予

掌握現代 Redux 的核心權威

這堂課我們從傳統 Redux 的冗餘痛點出發,對比了 Redux Toolkit 如何透過 createSliceconfigureStore 與 Immer 簡化開發流程。你已經理解 RTK 並非改變了 Redux 的本質,而是透過封裝最佳實踐,讓開發者能以更直覺、更安全的方式遵循 Redux 的核心原則。這套思維將支撐你撰寫出具備深度與說服力的教學文章。

接下來,我們將進入實作階段,動手建置開發環境。你將學習如何利用 Vite 快速啟動專案,並完成 RTK 與 TypeScript 的初始設定,為後續的 Slice 設計打下穩固的基礎。